+++ /dev/null
-/* gtkrbtree.c
- * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "gtkcssrbtreeprivate.h"
-
-#include "gtkdebug.h"
-
-typedef struct _GtkCssRbNode GtkCssRbNode;
-
-struct _GtkCssRbTree
-{
- guint ref_count;
-
- gsize element_size;
- gsize augment_size;
- GtkCssRbTreeAugmentFunc augment_func;
- GDestroyNotify clear_func;
- GDestroyNotify clear_augment_func;
-
- GtkCssRbNode *root;
-};
-
-struct _GtkCssRbNode
-{
- guint red :1;
- guint dirty :1;
-
- GtkCssRbNode *left;
- GtkCssRbNode *right;
- GtkCssRbNode *parent;
-};
-
-#define NODE_FROM_POINTER(ptr) ((GtkCssRbNode *) ((ptr) ? (((guchar *) (ptr)) - sizeof (GtkCssRbNode)) : NULL))
-#define NODE_TO_POINTER(node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkCssRbNode)) : NULL))
-#define NODE_TO_AUG_POINTER(tree, node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkCssRbNode) + (tree)->element_size) : NULL))
-
-static inline gsize
-gtk_css_rb_node_get_size (GtkCssRbTree *tree)
-{
- return sizeof (GtkCssRbNode) + tree->element_size + tree->augment_size;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_new (GtkCssRbTree *tree)
-{
- GtkCssRbNode *result;
-
- result = g_slice_alloc0 (gtk_css_rb_node_get_size (tree));
-
- result->red = TRUE;
- result->dirty = TRUE;
-
- return result;
-}
-
-static void
-gtk_css_rb_node_free (GtkCssRbTree *tree,
- GtkCssRbNode *node)
-{
- if (tree->clear_func)
- tree->clear_func (NODE_TO_POINTER (node));
- if (tree->clear_augment_func)
- tree->clear_augment_func (NODE_TO_AUG_POINTER (tree, node));
-
- g_slice_free1 (gtk_css_rb_node_get_size (tree), node);
-}
-
-static void
-gtk_css_rb_node_free_deep (GtkCssRbTree *tree,
- GtkCssRbNode *node)
-{
- GtkCssRbNode *right = node->right;
-
- if (node->left)
- gtk_css_rb_node_free_deep (tree, node->left);
-
- gtk_css_rb_node_free (tree, node);
-
- if (right)
- gtk_css_rb_node_free_deep (tree, right);
-}
-
-static void
-gtk_css_rb_node_mark_dirty (GtkCssRbNode *node,
- gboolean mark_parent)
-{
- if (node->dirty)
- return;
-
- node->dirty = TRUE;
-
- if (mark_parent && node->parent)
- gtk_css_rb_node_mark_dirty (node->parent, TRUE);
-}
-
-static void
-gtk_css_rb_node_clean (GtkCssRbTree *tree,
- GtkCssRbNode *node)
-{
- if (!node->dirty)
- return;
-
- node->dirty = FALSE;
- if (tree->augment_func)
- tree->augment_func (tree,
- NODE_TO_AUG_POINTER (tree, node),
- NODE_TO_POINTER (node),
- NODE_TO_POINTER (node->left),
- NODE_TO_POINTER (node->right));
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_first (GtkCssRbNode *node)
-{
- while (node->left)
- node = node->left;
-
- return node;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_last (GtkCssRbNode *node)
-{
- while (node->right)
- node = node->right;
-
- return node;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_previous (GtkCssRbNode *node)
-{
- GtkCssRbNode *parent;
-
- if (node->left)
- return gtk_css_rb_node_get_last (node->left);
-
- for (parent = node->parent; parent != NULL; parent = node->parent)
- {
- if (parent->right == node)
- return parent;
-
- node = parent;
- }
-
- return NULL;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_next (GtkCssRbNode *node)
-{
- GtkCssRbNode *parent;
-
- if (node->right)
- return gtk_css_rb_node_get_first (node->right);
-
- for (parent = node->parent; parent != NULL; parent = node->parent)
- {
- if (parent->left == node)
- return parent;
-
- node = parent;
- }
-
- return NULL;
-}
-
-static void
-gtk_css_rb_node_rotate_left (GtkCssRbTree *tree,
- GtkCssRbNode *node)
-{
- GtkCssRbNode *right;
-
- right = node->right;
-
- node->right = right->left;
- if (right->left)
- right->left->parent = node;
-
- right->parent = node->parent;
- if (node->parent)
- {
- if (node == node->parent->left)
- node->parent->left = right;
- else
- node->parent->right = right;
- }
- else
- {
- tree->root = right;
- }
-
- right->left = node;
- node->parent = right;
-
- gtk_css_rb_node_mark_dirty (node, FALSE);
- gtk_css_rb_node_mark_dirty (right, FALSE);
-}
-
-static void
-gtk_css_rb_node_rotate_right (GtkCssRbTree *tree,
- GtkCssRbNode *node)
-{
- GtkCssRbNode *left;
-
- left = node->left;
-
- node->left = left->right;
- if (left->right)
- left->right->parent = node;
-
- left->parent = node->parent;
- if (node->parent)
- {
- if (node == node->parent->right)
- node->parent->right = left;
- else
- node->parent->left = left;
- }
- else
- {
- tree->root = left;
- }
-
- /* link node and left */
- left->right = node;
- node->parent = left;
-
- gtk_css_rb_node_mark_dirty (node, FALSE);
- gtk_css_rb_node_mark_dirty (left, FALSE);
-}
-
-static gboolean
-is_red (GtkCssRbNode *node_or_null)
-{
- if (node_or_null == NULL)
- return FALSE;
- else
- return node_or_null->red;
-}
-
-static inline gboolean
-is_black (GtkCssRbNode *node_or_null)
-{
- return !is_red (node_or_null);
-}
-
-static void
-set_black (GtkCssRbNode *node_or_null)
-{
- if (node_or_null == NULL)
- return;
-
- node_or_null->red = FALSE;
-}
-
-static void
-set_red (GtkCssRbNode *node_or_null)
-{
- if (node_or_null == NULL)
- return;
-
- node_or_null->red = TRUE;
-}
-
-static void
-gtk_css_rb_tree_insert_fixup (GtkCssRbTree *tree,
- GtkCssRbNode *node)
-{
-
- /* check Red-Black properties */
- while (node->parent && is_red (node->parent))
- {
- /* we have a violation */
- g_assert (node->parent->parent);
-
- if (node->parent == node->parent->parent->left)
- {
- GtkCssRbNode *uncle = node->parent->parent->right;
-
- if (is_red (uncle))
- {
- /* uncle is red */
- set_black (node->parent);
- set_black (uncle);
- set_red (node->parent->parent);
- node = node->parent->parent;
- }
- else
- {
- /* uncle is black */
- if (node == node->parent->right)
- {
- /* make node a left child */
- node = node->parent;
- gtk_css_rb_node_rotate_left (tree, node);
- }
- /* recolor and rotate */
- set_black (node->parent);
- set_red (node->parent->parent);
- gtk_css_rb_node_rotate_right (tree, node->parent->parent);
- }
- }
- else
- {
- /* mirror image of above code */
- GtkCssRbNode *uncle = node->parent->parent->left;
-
- if (is_red (uncle))
- {
- /* uncle is red */
- set_black (node->parent);
- set_black (uncle);
- set_red (node->parent->parent);
- node = node->parent->parent;
- }
- else
- {
- /* uncle is black */
- if (node == node->parent->left)
- {
- node = node->parent;
- gtk_css_rb_node_rotate_right (tree, node);
- }
- set_black (node->parent);
- set_red (node->parent->parent);
- gtk_css_rb_node_rotate_left (tree, node->parent->parent);
- }
- }
- }
-
- set_black (tree->root);
-}
-
-static void
-gtk_css_rb_tree_remove_node_fixup (GtkCssRbTree *tree,
- GtkCssRbNode *node,
- GtkCssRbNode *parent)
-{
- while (node != tree->root && is_black (node))
- {
- if (node == parent->left)
- {
- GtkCssRbNode *w = parent->right;
-
- if (is_red (w))
- {
- set_black (w);
- set_red (parent);
- gtk_css_rb_node_rotate_left (tree, parent);
- w = parent->right;
- }
- if (is_black (w->left) && is_black (w->right))
- {
- set_red (w);
- node = parent;
- }
- else
- {
- if (is_black (w->right))
- {
- set_black (w->left);
- set_red (w);
- gtk_css_rb_node_rotate_right (tree, w);
- w = parent->right;
- }
- w->red = parent->red;
- set_black (parent);
- set_black (w->right);
- gtk_css_rb_node_rotate_left (tree, parent);
- node = tree->root;
- }
- }
- else
- {
- GtkCssRbNode *w = parent->left;
- if (is_red (w))
- {
- set_black (w);
- set_red (parent);
- gtk_css_rb_node_rotate_right (tree, parent);
- w = parent->left;
- }
- if (is_black (w->right) && is_black (w->left))
- {
- set_red (w);
- node = parent;
- }
- else
- {
- if (is_black (w->left))
- {
- set_black (w->right);
- set_red (w);
- gtk_css_rb_node_rotate_left (tree, w);
- w = parent->left;
- }
- w->red = parent->red;
- set_black (parent);
- set_black (w->left);
- gtk_css_rb_node_rotate_right (tree, parent);
- node = tree->root;
- }
- }
-
- parent = node->parent;
- }
-
- set_black (node);
-}
-
-GtkCssRbTree *
-gtk_css_rb_tree_new_for_size (gsize element_size,
- gsize augment_size,
- GtkCssRbTreeAugmentFunc augment_func,
- GDestroyNotify clear_func,
- GDestroyNotify clear_augment_func)
-{
- GtkCssRbTree *tree;
-
- tree = g_slice_new0 (GtkCssRbTree);
- tree->ref_count = 1;
-
- tree->element_size = element_size;
- tree->augment_size = augment_size;
- tree->augment_func = augment_func;
- tree->clear_func = clear_func;
- tree->clear_augment_func = clear_augment_func;
-
- return tree;
-}
-
-GtkCssRbTree *
-gtk_css_rb_tree_ref (GtkCssRbTree *tree)
-{
- tree->ref_count++;
-
- return tree;
-}
-
-void
-gtk_css_rb_tree_unref (GtkCssRbTree *tree)
-{
- tree->ref_count--;
- if (tree->ref_count > 0)
- return;
-
- if (tree->root)
- gtk_css_rb_node_free_deep (tree, tree->root);
-
- g_slice_free (GtkCssRbTree, tree);
-}
-
-gpointer
-gtk_css_rb_tree_get_first (GtkCssRbTree *tree)
-{
- if (tree->root == NULL)
- return NULL;
-
- return NODE_TO_POINTER (gtk_css_rb_node_get_first (tree->root));
-}
-
-gpointer
-gtk_css_rb_tree_get_last (GtkCssRbTree *tree)
-{
- if (tree->root == NULL)
- return NULL;
-
- return NODE_TO_POINTER (gtk_css_rb_node_get_last (tree->root));
-}
-
-gpointer
-gtk_css_rb_tree_get_previous (GtkCssRbTree *tree,
- gpointer node)
-{
- return NODE_TO_POINTER (gtk_css_rb_node_get_previous (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_css_rb_tree_get_next (GtkCssRbTree *tree,
- gpointer node)
-{
- return NODE_TO_POINTER (gtk_css_rb_node_get_next (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_css_rb_tree_get_root (GtkCssRbTree *tree)
-{
- return NODE_TO_POINTER (tree->root);
-}
-
-gpointer
-gtk_css_rb_tree_get_parent (GtkCssRbTree *tree,
- gpointer node)
-{
- return NODE_TO_POINTER (NODE_FROM_POINTER (node)->parent);
-}
-
-gpointer
-gtk_css_rb_tree_get_left (GtkCssRbTree *tree,
- gpointer node)
-{
- return NODE_TO_POINTER (NODE_FROM_POINTER (node)->left);
-}
-
-gpointer
-gtk_css_rb_tree_get_right (GtkCssRbTree *tree,
- gpointer node)
-{
- return NODE_TO_POINTER (NODE_FROM_POINTER (node)->right);
-}
-
-gpointer
-gtk_css_rb_tree_get_augment (GtkCssRbTree *tree,
- gpointer node)
-{
- GtkCssRbNode *rbnode = NODE_FROM_POINTER (node);
-
- gtk_css_rb_node_clean (tree, rbnode);
-
- return NODE_TO_AUG_POINTER (tree, rbnode);
-}
-
-void
-gtk_css_rb_tree_mark_dirty (GtkCssRbTree *tree,
- gpointer node)
-{
- gtk_css_rb_node_mark_dirty (NODE_FROM_POINTER (node), TRUE);
-}
-
-gpointer
-gtk_css_rb_tree_insert_before (GtkCssRbTree *tree,
- gpointer node)
-{
- GtkCssRbNode *result;
-
- /* setup new node */
- result = gtk_css_rb_node_new (tree);
-
- if (tree->root == NULL)
- {
- g_assert (node == NULL);
- tree->root = result;
- }
- else if (node == NULL)
- {
- return gtk_css_rb_tree_insert_after (tree, gtk_css_rb_tree_get_last (tree));
- }
- else
- {
- GtkCssRbNode *current = NODE_FROM_POINTER (node);
-
- if (current->left)
- {
- current = gtk_css_rb_node_get_last (current->left);
- current->right = result;
- }
- else
- {
- current->left = result;
- }
- result->parent = current;
- gtk_css_rb_node_mark_dirty (current, TRUE);
- }
-
- gtk_css_rb_tree_insert_fixup (tree, result);
-
- return NODE_TO_POINTER (result);
-}
-
-gpointer
-gtk_css_rb_tree_insert_after (GtkCssRbTree *tree,
- gpointer node)
-{
- GtkCssRbNode *result;
-
- /* setup new node */
- result = gtk_css_rb_node_new (tree);
-
- if (tree->root == NULL)
- {
- g_assert (node == NULL);
- tree->root = result;
- }
- else if (node == NULL)
- {
- return gtk_css_rb_tree_insert_before (tree, gtk_css_rb_tree_get_first (tree));
- }
- else
- {
- GtkCssRbNode *current = NODE_FROM_POINTER (node);
-
- if (current->right)
- {
- current = gtk_css_rb_node_get_first (current->right);
- current->left = result;
- }
- else
- {
- current->right = result;
- }
- result->parent = current;
- gtk_css_rb_node_mark_dirty (current, TRUE);
- }
-
- gtk_css_rb_tree_insert_fixup (tree, result);
-
- return NODE_TO_POINTER (result);
-}
-
-void
-gtk_css_rb_tree_remove (GtkCssRbTree *tree,
- gpointer node)
-{
- GtkCssRbNode *x, *y, *real_node;
-
- real_node = NODE_FROM_POINTER (node);
- y = real_node;
- if (y->left && y->right)
- {
- y = y->right;
-
- while (y->left)
- y = y->left;
- }
-
- /* x is y's only child, or nil */
- if (y->left)
- x = y->left;
- else
- x = y->right;
-
- /* remove y from the parent chain */
- if (x != NULL)
- x->parent = y->parent;
- if (y->parent)
- {
- if (y == y->parent->left)
- y->parent->left = x;
- else
- y->parent->right = x;
- gtk_css_rb_node_mark_dirty (y->parent, TRUE);
- }
- else
- {
- tree->root = x;
- }
-
- /* We need to clean up the validity of the tree.
- */
- if (is_black (y))
- gtk_css_rb_tree_remove_node_fixup (tree, x, y->parent);
-
- if (y != real_node)
- {
- /* Move the node over */
- if (is_red (real_node) != is_red (y))
- y->red = !y->red;
-
- y->left = real_node->left;
- if (y->left)
- y->left->parent = y;
- y->right = real_node->right;
- if (y->right)
- y->right->parent = y;
- y->parent = real_node->parent;
- if (y->parent)
- {
- if (y->parent->left == real_node)
- y->parent->left = y;
- else
- y->parent->right = y;
- gtk_css_rb_node_mark_dirty (y->parent, TRUE);
- }
- else
- {
- tree->root = y;
- }
- gtk_css_rb_node_mark_dirty (y, TRUE);
- }
-
- gtk_css_rb_node_free (tree, real_node);
-}
-
-void
-gtk_css_rb_tree_remove_all (GtkCssRbTree *tree)
-{
- if (tree->root)
- gtk_css_rb_node_free_deep (tree, tree->root);
-
- tree->root = NULL;
-}
-
-gpointer
-gtk_css_rb_tree_find (GtkCssRbTree *tree,
- gpointer *out_before,
- gpointer *out_after,
- GtkCssRbTreeFindFunc find_func,
- gpointer user_data)
-{
- GtkCssRbNode *node, *before = NULL, *after = NULL;
- int cmp;
-
- if (tree->root == NULL)
- {
- if (out_before)
- *out_before = NULL;
- if (out_after)
- *out_after = NULL;
-
- return NULL;
- }
-
- node = tree->root;
- for (cmp = find_func (tree, NODE_TO_POINTER (node), user_data);
- cmp != 0;
- cmp = find_func (tree, NODE_TO_POINTER (node), user_data))
- {
- if (cmp < 0)
- {
- before = node;
- node = node->right;
- }
- else /* cmp > 0 */
- {
- after = node;
- node = node->left;
- }
- if (node == NULL)
- {
- if (out_before)
- *out_before = NODE_TO_POINTER (before);
- if (out_after)
- *out_after = NODE_TO_POINTER (after);
- return NULL;;
- }
- }
-
- if (out_before)
- *out_before = NODE_TO_POINTER (gtk_css_rb_node_get_previous (node));
- if (out_after)
- *out_after = NODE_TO_POINTER (gtk_css_rb_node_get_next (node));
-
- return NODE_TO_POINTER (node);
-}
+++ /dev/null
-/* gtkrb_tree.h
- * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* A Red-Black Tree implementation used specifically by GtkTreeView.
- */
-#ifndef __GTK_CSS_RB_TREE_H__
-#define __GTK_CSS_RB_TREE_H__
-
-#include <glib.h>
-
-
-G_BEGIN_DECLS
-
-
-typedef struct _GtkCssRbTree GtkCssRbTree;
-
-typedef void (* GtkCssRbTreeAugmentFunc) (GtkCssRbTree *tree,
- gpointer node_augment,
- gpointer node,
- gpointer left,
- gpointer right);
-typedef int (* GtkCssRbTreeFindFunc) (GtkCssRbTree *tree,
- gpointer node,
- gpointer user_data);
-
-GtkCssRbTree * gtk_css_rb_tree_new_for_size (gsize element_size,
- gsize augment_size,
- GtkCssRbTreeAugmentFunc augment_func,
- GDestroyNotify clear_func,
- GDestroyNotify clear_augment_func);
-#define gtk_css_rb_tree_new(type, augment_type, augment_func, clear_func, clear_augment_func) \
- gtk_css_rb_tree_new_for_size (sizeof (type), sizeof (augment_type), (augment_func), (clear_func), (clear_augment_func))
-
-GtkCssRbTree * gtk_css_rb_tree_ref (GtkCssRbTree *tree);
-void gtk_css_rb_tree_unref (GtkCssRbTree *tree);
-
-gpointer gtk_css_rb_tree_get_first (GtkCssRbTree *tree);
-gpointer gtk_css_rb_tree_get_last (GtkCssRbTree *tree);
-gpointer gtk_css_rb_tree_get_previous (GtkCssRbTree *tree,
- gpointer node);
-gpointer gtk_css_rb_tree_get_next (GtkCssRbTree *tree,
- gpointer node);
-
-gpointer gtk_css_rb_tree_get_root (GtkCssRbTree *tree);
-gpointer gtk_css_rb_tree_get_parent (GtkCssRbTree *tree,
- gpointer node);
-gpointer gtk_css_rb_tree_get_left (GtkCssRbTree *tree,
- gpointer node);
-gpointer gtk_css_rb_tree_get_right (GtkCssRbTree *tree,
- gpointer node);
-gpointer gtk_css_rb_tree_get_augment (GtkCssRbTree *tree,
- gpointer node);
-
-void gtk_css_rb_tree_mark_dirty (GtkCssRbTree *tree,
- gpointer node);
-
-gpointer gtk_css_rb_tree_insert_before (GtkCssRbTree *tree,
- gpointer node);
-gpointer gtk_css_rb_tree_insert_after (GtkCssRbTree *tree,
- gpointer node);
-void gtk_css_rb_tree_remove (GtkCssRbTree *tree,
- gpointer node);
-void gtk_css_rb_tree_remove_all (GtkCssRbTree *tree);
-
-gpointer gtk_css_rb_tree_find (GtkCssRbTree *tree,
- gpointer *out_before,
- gpointer *out_after,
- GtkCssRbTreeFindFunc find_func,
- gpointer user_data);
-
-
-
-G_END_DECLS
-
-
-#endif /* __GTK_CSS_RB_TREE_H__ */
#include "gtkfilterlistmodel.h"
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
#include "gtkintl.h"
#include "gtkprivate.h"
gpointer user_data;
GDestroyNotify user_destroy;
- GtkCssRbTree *items; /* NULL if filter_func == NULL */
+ GtkRbTree *items; /* NULL if filter_func == NULL */
};
struct _GtkFilterListModelClass
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static FilterNode *
-gtk_filter_list_model_get_nth_filtered (GtkCssRbTree *tree,
- guint position,
- guint *out_unfiltered)
+gtk_filter_list_model_get_nth_filtered (GtkRbTree *tree,
+ guint position,
+ guint *out_unfiltered)
{
FilterNode *node, *tmp;
guint unfiltered;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
unfiltered = 0;
while (node)
{
- tmp = gtk_css_rb_tree_get_left (tree, node);
+ tmp = gtk_rb_tree_get_left (tree, node);
if (tmp)
{
- FilterAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_visible)
{
node = tmp;
unfiltered++;
- node = gtk_css_rb_tree_get_right (tree, node);
+ node = gtk_rb_tree_get_right (tree, node);
}
if (out_unfiltered)
}
static FilterNode *
-gtk_filter_list_model_get_nth (GtkCssRbTree *tree,
- guint position,
- guint *out_filtered)
+gtk_filter_list_model_get_nth (GtkRbTree *tree,
+ guint position,
+ guint *out_filtered)
{
FilterNode *node, *tmp;
guint filtered;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
filtered = 0;
while (node)
{
- tmp = gtk_css_rb_tree_get_left (tree, node);
+ tmp = gtk_rb_tree_get_left (tree, node);
if (tmp)
{
- FilterAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_items)
{
node = tmp;
if (node->visible)
filtered++;
- node = gtk_css_rb_tree_get_right (tree, node);
+ node = gtk_rb_tree_get_right (tree, node);
}
if (out_filtered)
if (!self->items)
return g_list_model_get_n_items (self->model);
- node = gtk_css_rb_tree_get_root (self->items);
+ node = gtk_rb_tree_get_root (self->items);
if (node == NULL)
return 0;
- aug = gtk_css_rb_tree_get_augment (self->items, node);
+ aug = gtk_rb_tree_get_augment (self->items, node);
return aug->n_visible;
}
for (i = 0; i < n_items; i++)
{
- node = gtk_css_rb_tree_insert_before (self->items, after);
+ node = gtk_rb_tree_insert_before (self->items, after);
node->visible = gtk_filter_list_model_run_filter (self, position + i);
if (node->visible)
n_visible++;
filter_removed = 0;
for (i = 0; i < removed; i++)
{
- FilterNode *next = gtk_css_rb_tree_get_next (self->items, node);
+ FilterNode *next = gtk_rb_tree_get_next (self->items, node);
if (node->visible)
filter_removed++;
- gtk_css_rb_tree_remove (self->items, node);
+ gtk_rb_tree_remove (self->items, node);
node = next;
}
g_signal_handlers_disconnect_by_func (self->model, gtk_filter_list_model_items_changed_cb, self);
g_clear_object (&self->model);
if (self->items)
- gtk_css_rb_tree_remove_all (self->items);
+ gtk_rb_tree_remove_all (self->items);
}
static void
self->filter_func = NULL;
self->user_data = NULL;
self->user_destroy = NULL;
- g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+ g_clear_pointer (&self->items, gtk_rb_tree_unref);
G_OBJECT_CLASS (gtk_filter_list_model_parent_class)->dispose (object);
-};
+}
static void
gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
static void
-gtk_filter_list_model_augment (GtkCssRbTree *filter,
- gpointer _aug,
- gpointer _node,
- gpointer left,
- gpointer right)
+gtk_filter_list_model_augment (GtkRbTree *filter,
+ gpointer _aug,
+ gpointer _node,
+ gpointer left,
+ gpointer right)
{
- FilterNode *node= _node;
+ FilterNode *node = _node;
FilterAugment *aug = _aug;
aug->n_items = 1;
if (left)
{
- FilterAugment *left_aug = gtk_css_rb_tree_get_augment (filter, left);
+ FilterAugment *left_aug = gtk_rb_tree_get_augment (filter, left);
aug->n_items += left_aug->n_items;
aug->n_visible += left_aug->n_visible;
}
if (right)
{
- FilterAugment *right_aug = gtk_css_rb_tree_get_augment (filter, right);
+ FilterAugment *right_aug = gtk_rb_tree_get_augment (filter, right);
aug->n_items += right_aug->n_items;
aug->n_visible += right_aug->n_visible;
}
if (!will_be_filtered)
{
- g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+ g_clear_pointer (&self->items, gtk_rb_tree_unref);
}
else if (!was_filtered)
{
guint i, n_items;
- self->items = gtk_css_rb_tree_new (FilterNode,
- FilterAugment,
- gtk_filter_list_model_augment,
- NULL, NULL);
+ self->items = gtk_rb_tree_new (FilterNode,
+ FilterAugment,
+ gtk_filter_list_model_augment,
+ NULL, NULL);
if (self->model)
{
n_items = g_list_model_get_n_items (self->model);
for (i = 0; i < n_items; i++)
{
- FilterNode *node = gtk_css_rb_tree_insert_before (self->items, NULL);
+ FilterNode *node = gtk_rb_tree_insert_before (self->items, NULL);
node->visible = TRUE;
}
}
last_change = 0;
n_is_visible = 0;
n_was_visible = 0;
- for (i = 0, node = gtk_css_rb_tree_get_first (self->items);
+ for (i = 0, node = gtk_rb_tree_get_first (self->items);
node != NULL;
- i++, node = gtk_css_rb_tree_get_next (self->items, node))
+ i++, node = gtk_rb_tree_get_next (self->items, node))
{
visible = gtk_filter_list_model_run_filter (self, i);
if (visible == node->visible)
}
node->visible = visible;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
first_change = MIN (n_is_visible, first_change);
if (visible)
n_is_visible++;
#include "gtkflattenlistmodel.h"
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
#include "gtkintl.h"
#include "gtkprivate.h"
GType item_type;
GListModel *model;
- GtkCssRbTree *items; /* NULL if model == NULL */
+ GtkRbTree *items; /* NULL if model == NULL */
};
struct _GtkFlattenListModelClass
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static FlattenNode *
-gtk_flatten_list_model_get_nth (GtkCssRbTree *tree,
+gtk_flatten_list_model_get_nth (GtkRbTree *tree,
guint position,
guint *model_position)
{
FlattenNode *node, *tmp;
guint model_n_items;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
while (node)
{
- tmp = gtk_css_rb_tree_get_left (tree, node);
+ tmp = gtk_rb_tree_get_left (tree, node);
if (tmp)
{
- FlattenAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ FlattenAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_items)
{
node = tmp;
break;
position -= model_n_items;
- node = gtk_css_rb_tree_get_right (tree, node);
+ node = gtk_rb_tree_get_right (tree, node);
}
if (model_position)
}
static FlattenNode *
-gtk_flatten_list_model_get_nth_model (GtkCssRbTree *tree,
+gtk_flatten_list_model_get_nth_model (GtkRbTree *tree,
guint position,
guint *items_before)
{
FlattenNode *node, *tmp;
guint before;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
before = 0;
while (node)
{
- tmp = gtk_css_rb_tree_get_left (tree, node);
+ tmp = gtk_rb_tree_get_left (tree, node);
if (tmp)
{
- FlattenAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ FlattenAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_models)
{
node = tmp;
position--;
before += g_list_model_get_n_items (node->model);
- node = gtk_css_rb_tree_get_right (tree, node);
+ node = gtk_rb_tree_get_right (tree, node);
}
if (items_before)
if (!self->items)
return 0;
- node = gtk_css_rb_tree_get_root (self->items);
+ node = gtk_rb_tree_get_root (self->items);
if (node == NULL)
return 0;
- aug = gtk_css_rb_tree_get_augment (self->items, node);
+ aug = gtk_rb_tree_get_augment (self->items, node);
return aug->n_items;
}
GtkFlattenListModel *self = node->list;
guint real_position;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
for (real_position = position;
- (parent = gtk_css_rb_tree_get_parent (self->items, node)) != NULL;
+ (parent = gtk_rb_tree_get_parent (self->items, node)) != NULL;
node = parent)
{
- FlattenNode *left = gtk_css_rb_tree_get_left (self->items, parent);
+ FlattenNode *left = gtk_rb_tree_get_left (self->items, parent);
if (left != node)
{
if (left)
{
- FlattenAugment *aug = gtk_css_rb_tree_get_augment (self->items, left);
+ FlattenAugment *aug = gtk_rb_tree_get_augment (self->items, left);
real_position += aug->n_items;
}
real_position += g_list_model_get_n_items (parent->model);
}
static void
-gtk_flatten_list_model_augment (GtkCssRbTree *flatten,
- gpointer _aug,
- gpointer _node,
- gpointer left,
- gpointer right)
+gtk_flatten_list_model_augment (GtkRbTree *flatten,
+ gpointer _aug,
+ gpointer _node,
+ gpointer left,
+ gpointer right)
{
- FlattenNode *node= _node;
+ FlattenNode *node = _node;
FlattenAugment *aug = _aug;
aug->n_items = g_list_model_get_n_items (node->model);
if (left)
{
- FlattenAugment *left_aug = gtk_css_rb_tree_get_augment (flatten, left);
+ FlattenAugment *left_aug = gtk_rb_tree_get_augment (flatten, left);
aug->n_items += left_aug->n_items;
aug->n_models += left_aug->n_models;
}
if (right)
{
- FlattenAugment *right_aug = gtk_css_rb_tree_get_augment (flatten, right);
+ FlattenAugment *right_aug = gtk_rb_tree_get_augment (flatten, right);
aug->n_items += right_aug->n_items;
aug->n_models += right_aug->n_models;
}
added = 0;
for (i = 0; i < n; i++)
{
- node = gtk_css_rb_tree_insert_before (self->items, after);
+ node = gtk_rb_tree_insert_before (self->items, after);
node->model = g_list_model_get_item (self->model, position + i);
g_warn_if_fail (g_type_is_a (g_list_model_get_item_type (node->model), self->item_type));
g_signal_connect (node->model,
real_removed = 0;
for (i = 0; i < removed; i++)
{
- FlattenNode *next = gtk_css_rb_tree_get_next (self->items, node);
+ FlattenNode *next = gtk_rb_tree_get_next (self->items, node);
real_removed += g_list_model_get_n_items (node->model);
- gtk_css_rb_tree_remove (self->items, node);
+ gtk_rb_tree_remove (self->items, node);
node = next;
}
{
g_signal_handlers_disconnect_by_func (self->model, gtk_flatten_list_model_model_items_changed_cb, self);
g_clear_object (&self->model);
- g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+ g_clear_pointer (&self->items, gtk_rb_tree_unref);
}
}
gtk_flatten_list_clear_model (self);
G_OBJECT_CLASS (gtk_flatten_list_model_parent_class)->dispose (object);
-};
+}
static void
gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class)
{
g_object_ref (model);
g_signal_connect (model, "items-changed", G_CALLBACK (gtk_flatten_list_model_model_items_changed_cb), self);
- self->items = gtk_css_rb_tree_new (FlattenNode,
- FlattenAugment,
- gtk_flatten_list_model_augment,
- gtk_flatten_list_model_clear_node,
- NULL);
+ self->items = gtk_rb_tree_new (FlattenNode,
+ FlattenAugment,
+ gtk_flatten_list_model_augment,
+ gtk_flatten_list_model_clear_node,
+ NULL);
added = gtk_flatten_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (model));
}
#include "gtkmaplistmodel.h"
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
#include "gtkintl.h"
#include "gtkprivate.h"
gpointer user_data;
GDestroyNotify user_destroy;
- GtkCssRbTree *items; /* NULL if map_func == NULL */
+ GtkRbTree *items; /* NULL if map_func == NULL */
};
struct _GtkMapListModelClass
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static MapNode *
-gtk_map_list_model_get_nth (GtkCssRbTree *tree,
- guint position,
- guint *out_start_pos)
+gtk_map_list_model_get_nth (GtkRbTree *tree,
+ guint position,
+ guint *out_start_pos)
{
MapNode *node, *tmp;
guint start_pos = position;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
while (node)
{
- tmp = gtk_css_rb_tree_get_left (tree, node);
+ tmp = gtk_rb_tree_get_left (tree, node);
if (tmp)
{
- MapAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ MapAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_items)
{
node = tmp;
}
position -= node->n_items;
- node = gtk_css_rb_tree_get_right (tree, node);
+ node = gtk_rb_tree_get_right (tree, node);
}
if (out_start_pos)
if (offset != position)
{
- MapNode *before = gtk_css_rb_tree_insert_before (self->items, node);
+ MapNode *before = gtk_rb_tree_insert_before (self->items, node);
before->n_items = position - offset;
node->n_items -= before->n_items;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
}
if (node->n_items > 1)
{
- MapNode *after = gtk_css_rb_tree_insert_after (self->items, node);
+ MapNode *after = gtk_rb_tree_insert_after (self->items, node);
after->n_items = node->n_items - 1;
node->n_items = 1;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
}
node->item = self->map_func (g_list_model_get_item (self->model, position), self->user_data);
end = start + node->n_items;
if (start == position && end <= position + removed)
{
- MapNode *next = gtk_css_rb_tree_get_next (self->items, node);
+ MapNode *next = gtk_rb_tree_get_next (self->items, node);
removed -= node->n_items;
- gtk_css_rb_tree_remove (self->items, node);
+ gtk_rb_tree_remove (self->items, node);
node = next;
}
else
{
node->n_items -= removed;
removed = 0;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
}
else if (start < position)
{
guint overlap = node->n_items - (position - start);
node->n_items -= overlap;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
removed -= overlap;
start = position;
- node = gtk_css_rb_tree_get_next (self->items, node);
+ node = gtk_rb_tree_get_next (self->items, node);
}
}
}
if (added)
{
if (node == NULL)
- node = gtk_css_rb_tree_insert_before (self->items, NULL);
+ node = gtk_rb_tree_insert_before (self->items, NULL);
else if (node->item)
- node = gtk_css_rb_tree_insert_after (self->items, node);
+ node = gtk_rb_tree_insert_after (self->items, node);
node->n_items += added;
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
}
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
self->map_func = NULL;
self->user_data = NULL;
self->user_destroy = NULL;
- g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+ g_clear_pointer (&self->items, gtk_rb_tree_unref);
G_OBJECT_CLASS (gtk_map_list_model_parent_class)->dispose (object);
-};
+}
static void
gtk_map_list_model_class_init (GtkMapListModelClass *class)
static void
-gtk_map_list_model_augment (GtkCssRbTree *map,
- gpointer _aug,
- gpointer _node,
- gpointer left,
- gpointer right)
+gtk_map_list_model_augment (GtkRbTree *map,
+ gpointer _aug,
+ gpointer _node,
+ gpointer left,
+ gpointer right)
{
- MapNode *node= _node;
+ MapNode *node = _node;
MapAugment *aug = _aug;
aug->n_items = node->n_items;
if (left)
{
- MapAugment *left_aug = gtk_css_rb_tree_get_augment (map, left);
+ MapAugment *left_aug = gtk_rb_tree_get_augment (map, left);
aug->n_items += left_aug->n_items;
}
if (right)
{
- MapAugment *right_aug = gtk_css_rb_tree_get_augment (map, right);
+ MapAugment *right_aug = gtk_rb_tree_get_augment (map, right);
aug->n_items += right_aug->n_items;
}
}
if (self->items)
{
- gtk_css_rb_tree_remove_all (self->items);
+ gtk_rb_tree_remove_all (self->items);
}
else
{
- self->items = gtk_css_rb_tree_new (MapNode,
- MapAugment,
- gtk_map_list_model_augment,
- gtk_map_list_model_clear_node,
- NULL);
+ self->items = gtk_rb_tree_new (MapNode,
+ MapAugment,
+ gtk_map_list_model_augment,
+ gtk_map_list_model_clear_node,
+ NULL);
}
n_items = g_list_model_get_n_items (self->model);
if (n_items)
{
- MapNode *node = gtk_css_rb_tree_insert_before (self->items, NULL);
+ MapNode *node = gtk_rb_tree_insert_before (self->items, NULL);
node->n_items = g_list_model_get_n_items (self->model);
- gtk_css_rb_tree_mark_dirty (self->items, node);
+ gtk_rb_tree_mark_dirty (self->items, node);
}
}
else
{
- g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+ g_clear_pointer (&self->items, gtk_rb_tree_unref);
}
}
--- /dev/null
+/* gtkrbtree.c
+ * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkrbtreeprivate.h"
+
+#include "gtkdebug.h"
+
+typedef struct _GtkRbNode GtkRbNode;
+
+struct _GtkRbTree
+{
+ guint ref_count;
+
+ gsize element_size;
+ gsize augment_size;
+ GtkRbTreeAugmentFunc augment_func;
+ GDestroyNotify clear_func;
+ GDestroyNotify clear_augment_func;
+
+ GtkRbNode *root;
+};
+
+struct _GtkRbNode
+{
+ guint red :1;
+ guint dirty :1;
+
+ GtkRbNode *left;
+ GtkRbNode *right;
+ GtkRbNode *parent;
+};
+
+#define NODE_FROM_POINTER(ptr) ((GtkRbNode *) ((ptr) ? (((guchar *) (ptr)) - sizeof (GtkRbNode)) : NULL))
+#define NODE_TO_POINTER(node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkRbNode)) : NULL))
+#define NODE_TO_AUG_POINTER(tree, node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkRbNode) + (tree)->element_size) : NULL))
+
+static inline gsize
+gtk_rb_node_get_size (GtkRbTree *tree)
+{
+ return sizeof (GtkRbNode) + tree->element_size + tree->augment_size;
+}
+
+static GtkRbNode *
+gtk_rb_node_new (GtkRbTree *tree)
+{
+ GtkRbNode *result;
+
+ result = g_slice_alloc0 (gtk_rb_node_get_size (tree));
+
+ result->red = TRUE;
+ result->dirty = TRUE;
+
+ return result;
+}
+
+static void
+gtk_rb_node_free (GtkRbTree *tree,
+ GtkRbNode *node)
+{
+ if (tree->clear_func)
+ tree->clear_func (NODE_TO_POINTER (node));
+ if (tree->clear_augment_func)
+ tree->clear_augment_func (NODE_TO_AUG_POINTER (tree, node));
+
+ g_slice_free1 (gtk_rb_node_get_size (tree), node);
+}
+
+static void
+gtk_rb_node_free_deep (GtkRbTree *tree,
+ GtkRbNode *node)
+{
+ GtkRbNode *right = node->right;
+
+ if (node->left)
+ gtk_rb_node_free_deep (tree, node->left);
+
+ gtk_rb_node_free (tree, node);
+
+ if (right)
+ gtk_rb_node_free_deep (tree, right);
+}
+
+static void
+gtk_rb_node_mark_dirty (GtkRbNode *node,
+ gboolean mark_parent)
+{
+ if (node->dirty)
+ return;
+
+ node->dirty = TRUE;
+
+ if (mark_parent && node->parent)
+ gtk_rb_node_mark_dirty (node->parent, TRUE);
+}
+
+static void
+gtk_rb_node_clean (GtkRbTree *tree,
+ GtkRbNode *node)
+{
+ if (!node->dirty)
+ return;
+
+ node->dirty = FALSE;
+ if (tree->augment_func)
+ tree->augment_func (tree,
+ NODE_TO_AUG_POINTER (tree, node),
+ NODE_TO_POINTER (node),
+ NODE_TO_POINTER (node->left),
+ NODE_TO_POINTER (node->right));
+}
+
+static GtkRbNode *
+gtk_rb_node_get_first (GtkRbNode *node)
+{
+ while (node->left)
+ node = node->left;
+
+ return node;
+}
+
+static GtkRbNode *
+gtk_rb_node_get_last (GtkRbNode *node)
+{
+ while (node->right)
+ node = node->right;
+
+ return node;
+}
+
+static GtkRbNode *
+gtk_rb_node_get_previous (GtkRbNode *node)
+{
+ GtkRbNode *parent;
+
+ if (node->left)
+ return gtk_rb_node_get_last (node->left);
+
+ for (parent = node->parent; parent != NULL; parent = node->parent)
+ {
+ if (parent->right == node)
+ return parent;
+
+ node = parent;
+ }
+
+ return NULL;
+}
+
+static GtkRbNode *
+gtk_rb_node_get_next (GtkRbNode *node)
+{
+ GtkRbNode *parent;
+
+ if (node->right)
+ return gtk_rb_node_get_first (node->right);
+
+ for (parent = node->parent; parent != NULL; parent = node->parent)
+ {
+ if (parent->left == node)
+ return parent;
+
+ node = parent;
+ }
+
+ return NULL;
+}
+
+static void
+gtk_rb_node_rotate_left (GtkRbTree *tree,
+ GtkRbNode *node)
+{
+ GtkRbNode *right;
+
+ right = node->right;
+
+ node->right = right->left;
+ if (right->left)
+ right->left->parent = node;
+
+ right->parent = node->parent;
+ if (node->parent)
+ {
+ if (node == node->parent->left)
+ node->parent->left = right;
+ else
+ node->parent->right = right;
+ }
+ else
+ {
+ tree->root = right;
+ }
+
+ right->left = node;
+ node->parent = right;
+
+ gtk_rb_node_mark_dirty (node, FALSE);
+ gtk_rb_node_mark_dirty (right, FALSE);
+}
+
+static void
+gtk_rb_node_rotate_right (GtkRbTree *tree,
+ GtkRbNode *node)
+{
+ GtkRbNode *left;
+
+ left = node->left;
+
+ node->left = left->right;
+ if (left->right)
+ left->right->parent = node;
+
+ left->parent = node->parent;
+ if (node->parent)
+ {
+ if (node == node->parent->right)
+ node->parent->right = left;
+ else
+ node->parent->left = left;
+ }
+ else
+ {
+ tree->root = left;
+ }
+
+ /* link node and left */
+ left->right = node;
+ node->parent = left;
+
+ gtk_rb_node_mark_dirty (node, FALSE);
+ gtk_rb_node_mark_dirty (left, FALSE);
+}
+
+static gboolean
+is_red (GtkRbNode *node_or_null)
+{
+ if (node_or_null == NULL)
+ return FALSE;
+ else
+ return node_or_null->red;
+}
+
+static inline gboolean
+is_black (GtkRbNode *node_or_null)
+{
+ return !is_red (node_or_null);
+}
+
+static void
+set_black (GtkRbNode *node_or_null)
+{
+ if (node_or_null == NULL)
+ return;
+
+ node_or_null->red = FALSE;
+}
+
+static void
+set_red (GtkRbNode *node_or_null)
+{
+ if (node_or_null == NULL)
+ return;
+
+ node_or_null->red = TRUE;
+}
+
+static void
+gtk_rb_tree_insert_fixup (GtkRbTree *tree,
+ GtkRbNode *node)
+{
+
+ /* check Red-Black properties */
+ while (node->parent && is_red (node->parent))
+ {
+ /* we have a violation */
+ g_assert (node->parent->parent);
+
+ if (node->parent == node->parent->parent->left)
+ {
+ GtkRbNode *uncle = node->parent->parent->right;
+
+ if (is_red (uncle))
+ {
+ /* uncle is red */
+ set_black (node->parent);
+ set_black (uncle);
+ set_red (node->parent->parent);
+ node = node->parent->parent;
+ }
+ else
+ {
+ /* uncle is black */
+ if (node == node->parent->right)
+ {
+ /* make node a left child */
+ node = node->parent;
+ gtk_rb_node_rotate_left (tree, node);
+ }
+ /* recolor and rotate */
+ set_black (node->parent);
+ set_red (node->parent->parent);
+ gtk_rb_node_rotate_right (tree, node->parent->parent);
+ }
+ }
+ else
+ {
+ /* mirror image of above code */
+ GtkRbNode *uncle = node->parent->parent->left;
+
+ if (is_red (uncle))
+ {
+ /* uncle is red */
+ set_black (node->parent);
+ set_black (uncle);
+ set_red (node->parent->parent);
+ node = node->parent->parent;
+ }
+ else
+ {
+ /* uncle is black */
+ if (node == node->parent->left)
+ {
+ node = node->parent;
+ gtk_rb_node_rotate_right (tree, node);
+ }
+ set_black (node->parent);
+ set_red (node->parent->parent);
+ gtk_rb_node_rotate_left (tree, node->parent->parent);
+ }
+ }
+ }
+
+ set_black (tree->root);
+}
+
+static void
+gtk_rb_tree_remove_node_fixup (GtkRbTree *tree,
+ GtkRbNode *node,
+ GtkRbNode *parent)
+{
+ while (node != tree->root && is_black (node))
+ {
+ if (node == parent->left)
+ {
+ GtkRbNode *w = parent->right;
+
+ if (is_red (w))
+ {
+ set_black (w);
+ set_red (parent);
+ gtk_rb_node_rotate_left (tree, parent);
+ w = parent->right;
+ }
+ if (is_black (w->left) && is_black (w->right))
+ {
+ set_red (w);
+ node = parent;
+ }
+ else
+ {
+ if (is_black (w->right))
+ {
+ set_black (w->left);
+ set_red (w);
+ gtk_rb_node_rotate_right (tree, w);
+ w = parent->right;
+ }
+ w->red = parent->red;
+ set_black (parent);
+ set_black (w->right);
+ gtk_rb_node_rotate_left (tree, parent);
+ node = tree->root;
+ }
+ }
+ else
+ {
+ GtkRbNode *w = parent->left;
+ if (is_red (w))
+ {
+ set_black (w);
+ set_red (parent);
+ gtk_rb_node_rotate_right (tree, parent);
+ w = parent->left;
+ }
+ if (is_black (w->right) && is_black (w->left))
+ {
+ set_red (w);
+ node = parent;
+ }
+ else
+ {
+ if (is_black (w->left))
+ {
+ set_black (w->right);
+ set_red (w);
+ gtk_rb_node_rotate_left (tree, w);
+ w = parent->left;
+ }
+ w->red = parent->red;
+ set_black (parent);
+ set_black (w->left);
+ gtk_rb_node_rotate_right (tree, parent);
+ node = tree->root;
+ }
+ }
+
+ parent = node->parent;
+ }
+
+ set_black (node);
+}
+
+GtkRbTree *
+gtk_rb_tree_new_for_size (gsize element_size,
+ gsize augment_size,
+ GtkRbTreeAugmentFunc augment_func,
+ GDestroyNotify clear_func,
+ GDestroyNotify clear_augment_func)
+{
+ GtkRbTree *tree;
+
+ tree = g_slice_new0 (GtkRbTree);
+ tree->ref_count = 1;
+
+ tree->element_size = element_size;
+ tree->augment_size = augment_size;
+ tree->augment_func = augment_func;
+ tree->clear_func = clear_func;
+ tree->clear_augment_func = clear_augment_func;
+
+ return tree;
+}
+
+GtkRbTree *
+gtk_rb_tree_ref (GtkRbTree *tree)
+{
+ tree->ref_count++;
+
+ return tree;
+}
+
+void
+gtk_rb_tree_unref (GtkRbTree *tree)
+{
+ tree->ref_count--;
+ if (tree->ref_count > 0)
+ return;
+
+ if (tree->root)
+ gtk_rb_node_free_deep (tree, tree->root);
+
+ g_slice_free (GtkRbTree, tree);
+}
+
+gpointer
+gtk_rb_tree_get_first (GtkRbTree *tree)
+{
+ if (tree->root == NULL)
+ return NULL;
+
+ return NODE_TO_POINTER (gtk_rb_node_get_first (tree->root));
+}
+
+gpointer
+gtk_rb_tree_get_last (GtkRbTree *tree)
+{
+ if (tree->root == NULL)
+ return NULL;
+
+ return NODE_TO_POINTER (gtk_rb_node_get_last (tree->root));
+}
+
+gpointer
+gtk_rb_tree_get_previous (GtkRbTree *tree,
+ gpointer node)
+{
+ return NODE_TO_POINTER (gtk_rb_node_get_previous (NODE_FROM_POINTER (node)));
+}
+
+gpointer
+gtk_rb_tree_get_next (GtkRbTree *tree,
+ gpointer node)
+{
+ return NODE_TO_POINTER (gtk_rb_node_get_next (NODE_FROM_POINTER (node)));
+}
+
+gpointer
+gtk_rb_tree_get_root (GtkRbTree *tree)
+{
+ return NODE_TO_POINTER (tree->root);
+}
+
+gpointer
+gtk_rb_tree_get_parent (GtkRbTree *tree,
+ gpointer node)
+{
+ return NODE_TO_POINTER (NODE_FROM_POINTER (node)->parent);
+}
+
+gpointer
+gtk_rb_tree_get_left (GtkRbTree *tree,
+ gpointer node)
+{
+ return NODE_TO_POINTER (NODE_FROM_POINTER (node)->left);
+}
+
+gpointer
+gtk_rb_tree_get_right (GtkRbTree *tree,
+ gpointer node)
+{
+ return NODE_TO_POINTER (NODE_FROM_POINTER (node)->right);
+}
+
+gpointer
+gtk_rb_tree_get_augment (GtkRbTree *tree,
+ gpointer node)
+{
+ GtkRbNode *rbnode = NODE_FROM_POINTER (node);
+
+ gtk_rb_node_clean (tree, rbnode);
+
+ return NODE_TO_AUG_POINTER (tree, rbnode);
+}
+
+void
+gtk_rb_tree_mark_dirty (GtkRbTree *tree,
+ gpointer node)
+{
+ gtk_rb_node_mark_dirty (NODE_FROM_POINTER (node), TRUE);
+}
+
+gpointer
+gtk_rb_tree_insert_before (GtkRbTree *tree,
+ gpointer node)
+{
+ GtkRbNode *result;
+
+ /* setup new node */
+ result = gtk_rb_node_new (tree);
+
+ if (tree->root == NULL)
+ {
+ g_assert (node == NULL);
+ tree->root = result;
+ }
+ else if (node == NULL)
+ {
+ return gtk_rb_tree_insert_after (tree, gtk_rb_tree_get_last (tree));
+ }
+ else
+ {
+ GtkRbNode *current = NODE_FROM_POINTER (node);
+
+ if (current->left)
+ {
+ current = gtk_rb_node_get_last (current->left);
+ current->right = result;
+ }
+ else
+ {
+ current->left = result;
+ }
+ result->parent = current;
+ gtk_rb_node_mark_dirty (current, TRUE);
+ }
+
+ gtk_rb_tree_insert_fixup (tree, result);
+
+ return NODE_TO_POINTER (result);
+}
+
+gpointer
+gtk_rb_tree_insert_after (GtkRbTree *tree,
+ gpointer node)
+{
+ GtkRbNode *result;
+
+ /* setup new node */
+ result = gtk_rb_node_new (tree);
+
+ if (tree->root == NULL)
+ {
+ g_assert (node == NULL);
+ tree->root = result;
+ }
+ else if (node == NULL)
+ {
+ return gtk_rb_tree_insert_before (tree, gtk_rb_tree_get_first (tree));
+ }
+ else
+ {
+ GtkRbNode *current = NODE_FROM_POINTER (node);
+
+ if (current->right)
+ {
+ current = gtk_rb_node_get_first (current->right);
+ current->left = result;
+ }
+ else
+ {
+ current->right = result;
+ }
+ result->parent = current;
+ gtk_rb_node_mark_dirty (current, TRUE);
+ }
+
+ gtk_rb_tree_insert_fixup (tree, result);
+
+ return NODE_TO_POINTER (result);
+}
+
+void
+gtk_rb_tree_remove (GtkRbTree *tree,
+ gpointer node)
+{
+ GtkRbNode *x, *y, *real_node;
+
+ real_node = NODE_FROM_POINTER (node);
+ y = real_node;
+ if (y->left && y->right)
+ {
+ y = y->right;
+
+ while (y->left)
+ y = y->left;
+ }
+
+ /* x is y's only child, or nil */
+ if (y->left)
+ x = y->left;
+ else
+ x = y->right;
+
+ /* remove y from the parent chain */
+ if (x != NULL)
+ x->parent = y->parent;
+ if (y->parent)
+ {
+ if (y == y->parent->left)
+ y->parent->left = x;
+ else
+ y->parent->right = x;
+ gtk_rb_node_mark_dirty (y->parent, TRUE);
+ }
+ else
+ {
+ tree->root = x;
+ }
+
+ /* We need to clean up the validity of the tree.
+ */
+ if (is_black (y))
+ gtk_rb_tree_remove_node_fixup (tree, x, y->parent);
+
+ if (y != real_node)
+ {
+ /* Move the node over */
+ if (is_red (real_node) != is_red (y))
+ y->red = !y->red;
+
+ y->left = real_node->left;
+ if (y->left)
+ y->left->parent = y;
+ y->right = real_node->right;
+ if (y->right)
+ y->right->parent = y;
+ y->parent = real_node->parent;
+ if (y->parent)
+ {
+ if (y->parent->left == real_node)
+ y->parent->left = y;
+ else
+ y->parent->right = y;
+ gtk_rb_node_mark_dirty (y->parent, TRUE);
+ }
+ else
+ {
+ tree->root = y;
+ }
+ gtk_rb_node_mark_dirty (y, TRUE);
+ }
+
+ gtk_rb_node_free (tree, real_node);
+}
+
+void
+gtk_rb_tree_remove_all (GtkRbTree *tree)
+{
+ if (tree->root)
+ gtk_rb_node_free_deep (tree, tree->root);
+
+ tree->root = NULL;
+}
+
+gpointer
+gtk_rb_tree_find (GtkRbTree *tree,
+ gpointer *out_before,
+ gpointer *out_after,
+ GtkRbTreeFindFunc find_func,
+ gpointer user_data)
+{
+ GtkRbNode *node, *before = NULL, *after = NULL;
+ int cmp;
+
+ if (tree->root == NULL)
+ {
+ if (out_before)
+ *out_before = NULL;
+ if (out_after)
+ *out_after = NULL;
+
+ return NULL;
+ }
+
+ node = tree->root;
+ for (cmp = find_func (tree, NODE_TO_POINTER (node), user_data);
+ cmp != 0;
+ cmp = find_func (tree, NODE_TO_POINTER (node), user_data))
+ {
+ if (cmp < 0)
+ {
+ before = node;
+ node = node->right;
+ }
+ else /* cmp > 0 */
+ {
+ after = node;
+ node = node->left;
+ }
+ if (node == NULL)
+ {
+ if (out_before)
+ *out_before = NODE_TO_POINTER (before);
+ if (out_after)
+ *out_after = NODE_TO_POINTER (after);
+ return NULL;;
+ }
+ }
+
+ if (out_before)
+ *out_before = NODE_TO_POINTER (gtk_rb_node_get_previous (node));
+ if (out_after)
+ *out_after = NODE_TO_POINTER (gtk_rb_node_get_next (node));
+
+ return NODE_TO_POINTER (node);
+}
--- /dev/null
+/* gtkrbtree.h
+ * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* A Red-Black Tree implementation used specifically by GtkTreeView.
+ */
+#ifndef __GTK_RB_TREE_H__
+#define __GTK_RB_TREE_H__
+
+#include <glib.h>
+
+
+G_BEGIN_DECLS
+
+
+typedef struct _GtkRbTree GtkRbTree;
+
+typedef void (* GtkRbTreeAugmentFunc) (GtkRbTree *tree,
+ gpointer node_augment,
+ gpointer node,
+ gpointer left,
+ gpointer right);
+typedef int (* GtkRbTreeFindFunc) (GtkRbTree *tree,
+ gpointer node,
+ gpointer user_data);
+
+GtkRbTree * gtk_rb_tree_new_for_size (gsize element_size,
+ gsize augment_size,
+ GtkRbTreeAugmentFunc augment_func,
+ GDestroyNotify clear_func,
+ GDestroyNotify clear_augment_func);
+#define gtk_rb_tree_new(type, augment_type, augment_func, clear_func, clear_augment_func) \
+ gtk_rb_tree_new_for_size (sizeof (type), sizeof (augment_type), (augment_func), (clear_func), (clear_augment_func))
+
+GtkRbTree * gtk_rb_tree_ref (GtkRbTree *tree);
+void gtk_rb_tree_unref (GtkRbTree *tree);
+
+gpointer gtk_rb_tree_get_first (GtkRbTree *tree);
+gpointer gtk_rb_tree_get_last (GtkRbTree *tree);
+gpointer gtk_rb_tree_get_previous (GtkRbTree *tree,
+ gpointer node);
+gpointer gtk_rb_tree_get_next (GtkRbTree *tree,
+ gpointer node);
+
+gpointer gtk_rb_tree_get_root (GtkRbTree *tree);
+gpointer gtk_rb_tree_get_parent (GtkRbTree *tree,
+ gpointer node);
+gpointer gtk_rb_tree_get_left (GtkRbTree *tree,
+ gpointer node);
+gpointer gtk_rb_tree_get_right (GtkRbTree *tree,
+ gpointer node);
+gpointer gtk_rb_tree_get_augment (GtkRbTree *tree,
+ gpointer node);
+
+void gtk_rb_tree_mark_dirty (GtkRbTree *tree,
+ gpointer node);
+
+gpointer gtk_rb_tree_insert_before (GtkRbTree *tree,
+ gpointer node);
+gpointer gtk_rb_tree_insert_after (GtkRbTree *tree,
+ gpointer node);
+void gtk_rb_tree_remove (GtkRbTree *tree,
+ gpointer node);
+void gtk_rb_tree_remove_all (GtkRbTree *tree);
+
+gpointer gtk_rb_tree_find (GtkRbTree *tree,
+ gpointer *out_before,
+ gpointer *out_after,
+ GtkRbTreeFindFunc find_func,
+ gpointer user_data);
+
+
+G_END_DECLS
+
+
+#endif /* __GTK_RB_TREE_H__ */
#include "gtkslicelistmodel.h"
-#include "gtkcssrbtreeprivate.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtktreelistmodel.h"
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
#include "gtkintl.h"
#include "gtkprivate.h"
{
GListModel *model;
GtkTreeListRow *row;
- GtkCssRbTree *children;
+ GtkRbTree *children;
union {
TreeNode *parent;
GtkTreeListModel *list;
tree_node_get_nth_child (TreeNode *node,
guint position)
{
- GtkCssRbTree *tree;
+ GtkRbTree *tree;
TreeNode *child, *tmp;
TreeAugment *aug;
tree = node->children;
- child = gtk_css_rb_tree_get_root (tree);
+ child = gtk_rb_tree_get_root (tree);
while (child)
{
- tmp = gtk_css_rb_tree_get_left (tree, child);
+ tmp = gtk_rb_tree_get_left (tree, child);
if (tmp)
{
- aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_local)
{
child = tmp;
position--;
- child = gtk_css_rb_tree_get_right (tree, child);
+ child = gtk_rb_tree_get_right (tree, child);
}
return NULL;
if (node->children == NULL)
return 0;
- child_node = gtk_css_rb_tree_get_root (node->children);
+ child_node = gtk_rb_tree_get_root (node->children);
if (child_node == NULL)
return 0;
- child_aug = gtk_css_rb_tree_get_augment (node->children, child_node);
+ child_aug = gtk_rb_tree_get_augment (node->children, child_node);
return child_aug->n_items;
}
static guint
-tree_node_get_local_position (GtkCssRbTree *tree,
- TreeNode *node)
+tree_node_get_local_position (GtkRbTree *tree,
+ TreeNode *node)
{
TreeNode *left, *parent;
TreeAugment *left_aug;
guint n;
- left = gtk_css_rb_tree_get_left (tree, node);
+ left = gtk_rb_tree_get_left (tree, node);
if (left)
{
- left_aug = gtk_css_rb_tree_get_augment (tree, left);
+ left_aug = gtk_rb_tree_get_augment (tree, left);
n = left_aug->n_local;
}
else
n = 0;
}
- for (parent = gtk_css_rb_tree_get_parent (tree, node);
+ for (parent = gtk_rb_tree_get_parent (tree, node);
parent;
- parent = gtk_css_rb_tree_get_parent (tree, node))
+ parent = gtk_rb_tree_get_parent (tree, node))
{
- left = gtk_css_rb_tree_get_left (tree, parent);
+ left = gtk_rb_tree_get_left (tree, parent);
if (left == node)
{
/* we are the left node, nothing changes */
n++;
if (left)
{
- left_aug = gtk_css_rb_tree_get_augment (tree, left);
+ left_aug = gtk_rb_tree_get_augment (tree, left);
n += left_aug->n_local;
}
}
static guint
tree_node_get_position (TreeNode *node)
{
- GtkCssRbTree *tree;
+ GtkRbTree *tree;
TreeNode *left, *parent;
TreeAugment *left_aug;
guint n;
{
tree = node->parent->children;
- left = gtk_css_rb_tree_get_left (tree, node);
+ left = gtk_rb_tree_get_left (tree, node);
if (left)
{
- left_aug = gtk_css_rb_tree_get_augment (tree, left);
+ left_aug = gtk_rb_tree_get_augment (tree, left);
n += left_aug->n_items;
}
- for (parent = gtk_css_rb_tree_get_parent (tree, node);
+ for (parent = gtk_rb_tree_get_parent (tree, node);
parent;
- parent = gtk_css_rb_tree_get_parent (tree, node))
+ parent = gtk_rb_tree_get_parent (tree, node))
{
- left = gtk_css_rb_tree_get_left (tree, parent);
+ left = gtk_rb_tree_get_left (tree, parent);
if (left == node)
{
/* we are the left node, nothing changes */
n += 1 + tree_node_get_n_children (parent);
if (left)
{
- left_aug = gtk_css_rb_tree_get_augment (tree, left);
+ left_aug = gtk_rb_tree_get_augment (tree, left);
n += left_aug->n_items;
}
}
!node->is_root;
node = node->parent)
{
- gtk_css_rb_tree_mark_dirty (node->parent->children, node);
+ gtk_rb_tree_mark_dirty (node->parent->children, node);
}
}
gtk_tree_list_model_get_nth (GtkTreeListModel *self,
guint position)
{
- GtkCssRbTree *tree;
+ GtkRbTree *tree;
TreeNode *node, *tmp;
guint n_children;
return NULL;
tree = self->root_node.children;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
while (TRUE)
{
- tmp = gtk_css_rb_tree_get_left (tree, node);
+ tmp = gtk_rb_tree_get_left (tree, node);
if (tmp)
{
- TreeAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+ TreeAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
if (position < aug->n_items)
{
node = tmp;
if (position < n_children)
{
tree = node->children;
- node = gtk_css_rb_tree_get_root (tree);
+ node = gtk_rb_tree_get_root (tree);
continue;
}
position -= n_children;
- node = gtk_css_rb_tree_get_right (tree, node);
+ node = gtk_rb_tree_get_right (tree, node);
}
g_return_val_if_reached (NULL);
for (i = 0; i < removed; i++)
{
tmp = child;
- child = gtk_css_rb_tree_get_next (node->children, child);
- gtk_css_rb_tree_remove (node->children, tmp);
+ child = gtk_rb_tree_get_next (node->children, child);
+ gtk_rb_tree_remove (node->children, tmp);
}
}
else
tree_added = added;
for (i = 0; i < added; i++)
{
- child = gtk_css_rb_tree_insert_before (node->children, child);
+ child = gtk_rb_tree_insert_before (node->children, child);
child->parent = node;
}
if (self->autoexpand)
for (i = 0; i < added; i++)
{
tree_added += gtk_tree_list_model_expand_node (self, child);
- child = gtk_css_rb_tree_get_next (node->children, child);
+ child = gtk_rb_tree_get_next (node->children, child);
}
}
g_object_unref (node->model);
}
if (node->children)
- gtk_css_rb_tree_unref (node->children);
+ gtk_rb_tree_unref (node->children);
}
static void
-gtk_tree_list_model_augment (GtkCssRbTree *tree,
- gpointer _aug,
- gpointer _node,
- gpointer left,
- gpointer right)
+gtk_tree_list_model_augment (GtkRbTree *tree,
+ gpointer _aug,
+ gpointer _node,
+ gpointer left,
+ gpointer right)
{
TreeAugment *aug = _aug;
if (left)
{
- TreeAugment *left_aug = gtk_css_rb_tree_get_augment (tree, left);
+ TreeAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
aug->n_items += left_aug->n_items;
aug->n_local += left_aug->n_local;
}
if (right)
{
- TreeAugment *right_aug = gtk_css_rb_tree_get_augment (tree, right);
+ TreeAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
aug->n_items += right_aug->n_items;
aug->n_local += right_aug->n_local;
}
"items-changed",
G_CALLBACK (gtk_tree_list_model_items_changed_cb),
self);
- self->children = gtk_css_rb_tree_new (TreeNode,
- TreeAugment,
- gtk_tree_list_model_augment,
- gtk_tree_list_model_clear_node,
- NULL);
+ self->children = gtk_rb_tree_new (TreeNode,
+ TreeAugment,
+ gtk_tree_list_model_augment,
+ gtk_tree_list_model_clear_node,
+ NULL);
n = g_list_model_get_n_items (model);
node = NULL;
for (i = 0; i < n; i++)
{
- node = gtk_css_rb_tree_insert_after (self->children, node);
+ node = gtk_rb_tree_insert_after (self->children, node);
node->parent = self;
if (list->autoexpand)
gtk_tree_list_model_expand_node (list, node);
n_items = tree_node_get_n_children (node);
- g_clear_pointer (&node->children, gtk_css_rb_tree_unref);
+ g_clear_pointer (&node->children, gtk_rb_tree_unref);
g_clear_object (&node->model);
tree_node_mark_dirty (node);
self->user_destroy (self->user_data);
G_OBJECT_CLASS (gtk_tree_list_model_parent_class)->finalize (object);
-};
+}
static void
gtk_tree_list_model_class_init (GtkTreeListModelClass *class)
self->node->row = NULL;
G_OBJECT_CLASS (gtk_tree_list_row_parent_class)->dispose (object);
-};
+}
static void
gtk_tree_list_row_class_init (GtkTreeListRowClass *class)
'gtkcssparser.c',
'gtkcsspathnode.c',
'gtkcsspositionvalue.c',
- 'gtkcssrbtree.c',
'gtkcssrepeatvalue.c',
'gtkcssrgbavalue.c',
'gtkcssselector.c',
'gtkprintutils.c',
'gtkprivate.c',
'gtkprogresstracker.c',
+ 'gtkrbtree.c',
'gtkquery.c',
'gtkscaler.c',
'gtksearchengine.c',
+++ /dev/null
-/* GtkRBTree tests.
- *
- * Copyright (C) 2011, Red Hat, Inc.
- * Authors: Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <locale.h>
-
-#include <gtk/gtk.h>
-
-#include "gtk/gtkcssrbtreeprivate.h"
-
-typedef struct _Node Node;
-typedef struct _Aug Aug;
-
-struct _Node {
- guint unused;
-};
-
-struct _Aug {
- guint n_items;
-};
-
-static void
-augment (GtkCssRbTree *tree,
- gpointer _aug,
- gpointer _node,
- gpointer left,
- gpointer right)
-{
- Aug *aug = _aug;
-
- aug->n_items = 1;
-
- if (left)
- {
- Aug *left_aug = gtk_css_rb_tree_get_augment (tree, left);
-
- aug->n_items += left_aug->n_items;
- }
-
- if (right)
- {
- Aug *right_aug = gtk_css_rb_tree_get_augment (tree, right);
-
- aug->n_items += right_aug->n_items;
- }
-}
-
-static Node *
-get (GtkCssRbTree *tree,
- guint pos)
-{
- Node *node, *tmp;
-
- node = gtk_css_rb_tree_get_root (tree);
-
- while (node)
- {
- tmp = gtk_css_rb_tree_get_left (tree, node);
- if (tmp)
- {
- Aug *aug = gtk_css_rb_tree_get_augment (tree, tmp);
- if (pos < aug->n_items)
- {
- node = tmp;
- continue;
- }
- pos -= aug->n_items;
- }
-
- if (pos < 1)
- break;
- pos--;
-
- node = gtk_css_rb_tree_get_right (tree, node);
- }
-
- return node;
-}
-
-static void
-add (GtkCssRbTree *tree,
- guint pos)
-{
- Node *node = get (tree, pos);
-
- gtk_css_rb_tree_insert_before (tree, node);
-}
-
-static void
-delete (GtkCssRbTree *tree,
- guint pos)
-{
- Node *node = get (tree, pos);
-
- gtk_css_rb_tree_remove (tree, node);
-}
-
-static guint
-print_node (GtkCssRbTree *tree,
- Node *node,
- guint depth,
- const char *prefix,
- guint n)
-{
- Node *child;
-
- child = gtk_css_rb_tree_get_left (tree, node);
- if (child)
- n = print_node (tree, child, depth + 1, "/", n);
- g_print ("%*s %u\n", 2 * depth, prefix, n);
- n++;
- child = gtk_css_rb_tree_get_right (tree, node);
- if (child)
- n = print_node (tree, child, depth + 1, "\\", n);
-
- return n;
-}
-
-static void
-print (GtkCssRbTree *tree)
-{
- print_node (tree, gtk_css_rb_tree_get_root (tree), 0, "", 0);
-}
-
-static void
-test_crash (void)
-{
- GtkCssRbTree *tree;
- guint i;
-
- tree = gtk_css_rb_tree_new (Node, Aug, augment, NULL, NULL);
-
- for (i = 0; i < 300; i++)
- add (tree, i);
- print (tree);
- delete (tree, 144);
- add (tree, 56);
- delete (tree, 113);
- delete (tree, 278);
- delete (tree, 45);
- delete (tree, 108);
- delete (tree, 41);
- add (tree, 56);
- add (tree, 200);
- delete (tree, 127);
- delete (tree, 222);
- add (tree, 80);
- add (tree, 143);
- add (tree, 216);
- delete (tree, 177);
- delete (tree, 193);
- add (tree, 190);
- delete (tree, 288);
- add (tree, 45);
- add (tree, 57);
- add (tree, 211);
- delete (tree, 103);
- add (tree, 152);
- delete (tree, 60);
- add (tree, 185);
- delete (tree, 167);
- add (tree, 92);
- delete (tree, 104);
- delete (tree, 110);
- delete (tree, 115);
- add (tree, 32);
- delete (tree, 44);
- add (tree, 159);
- add (tree, 271);
- delete (tree, 35);
- add (tree, 250);
- delete (tree, 36);
- add (tree, 284);
- delete (tree, 82);
- delete (tree, 248);
- add (tree, 22);
- delete (tree, 284);
- add (tree, 88);
- delete (tree, 182);
- add (tree, 70);
- add (tree, 55);
- delete (tree, 6);
- add (tree, 85);
- delete (tree, 36);
- delete (tree, 33);
- delete (tree, 108);
- add (tree, 229);
- delete (tree, 269);
- add (tree, 20);
- add (tree, 170);
- delete (tree, 154);
- add (tree, 26);
- add (tree, 211);
- delete (tree, 167);
- add (tree, 183);
- add (tree, 292);
- delete (tree, 2);
- add (tree, 5);
- delete (tree, 14);
- delete (tree, 91);
- add (tree, 172);
- add (tree, 99);
- delete (tree, 3);
- delete (tree, 74);
- delete (tree, 122);
- add (tree, 87);
- add (tree, 176);
- delete (tree, 294);
- add (tree, 169);
- delete (tree, 41);
- add (tree, 95);
- delete (tree, 185);
- add (tree, 218);
- delete (tree, 62);
- delete (tree, 175);
- add (tree, 196);
- delete (tree, 33);
- delete (tree, 46);
- add (tree, 30);
- add (tree, 72);
- delete (tree, 196);
- delete (tree, 291);
- add (tree, 198);
- delete (tree, 181);
- add (tree, 105);
- delete (tree, 75);
- add (tree, 30);
- add (tree, 261);
- delete (tree, 284);
- delete (tree, 214);
- delete (tree, 134);
- add (tree, 153);
- delete (tree, 46);
- add (tree, 154);
- add (tree, 266);
- delete (tree, 272);
- delete (tree, 150);
- add (tree, 131);
- delete (tree, 208);
- add (tree, 241);
- add (tree, 31);
- add (tree, 151);
- add (tree, 266);
- delete (tree, 285);
- add (tree, 178);
- add (tree, 159);
- add (tree, 203);
- delete (tree, 266);
- add (tree, 52);
- delete (tree, 104);
- add (tree, 243);
- delete (tree, 12);
- add (tree, 20);
- delete (tree, 68);
- print (tree);
- delete (tree, 102);
-
- gtk_css_rb_tree_unref (tree);
-}
-
-int
-main (int argc, char *argv[])
-{
- g_test_init (&argc, &argv, NULL);
- setlocale (LC_ALL, "C");
- g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
-
- g_test_add_func ("/csrbtree/crash", test_crash);
-
- return g_test_run ();
-}
['cellarea'],
['check-icon-names'],
['cssprovider'],
- ['cssrbtree-crash', ['../../gtk/gtkcssrbtree.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
+ ['rbtree-crash', ['../../gtk/gtkrbtree.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
['defaultvalue'],
['entry'],
['filterlistmodel'],
--- /dev/null
+/* GtkRBTree tests.
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ * Authors: Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <locale.h>
+
+#include <gtk/gtk.h>
+
+#include "gtk/gtkrbtreeprivate.h"
+
+typedef struct _Node Node;
+typedef struct _Aug Aug;
+
+struct _Node {
+ guint unused;
+};
+
+struct _Aug {
+ guint n_items;
+};
+
+static void
+augment (GtkRbTree *tree,
+ gpointer _aug,
+ gpointer _node,
+ gpointer left,
+ gpointer right)
+{
+ Aug *aug = _aug;
+
+ aug->n_items = 1;
+
+ if (left)
+ {
+ Aug *left_aug = gtk_rb_tree_get_augment (tree, left);
+
+ aug->n_items += left_aug->n_items;
+ }
+
+ if (right)
+ {
+ Aug *right_aug = gtk_rb_tree_get_augment (tree, right);
+
+ aug->n_items += right_aug->n_items;
+ }
+}
+
+static Node *
+get (GtkRbTree *tree,
+ guint pos)
+{
+ Node *node, *tmp;
+
+ node = gtk_rb_tree_get_root (tree);
+
+ while (node)
+ {
+ tmp = gtk_rb_tree_get_left (tree, node);
+ if (tmp)
+ {
+ Aug *aug = gtk_rb_tree_get_augment (tree, tmp);
+ if (pos < aug->n_items)
+ {
+ node = tmp;
+ continue;
+ }
+ pos -= aug->n_items;
+ }
+
+ if (pos < 1)
+ break;
+ pos--;
+
+ node = gtk_rb_tree_get_right (tree, node);
+ }
+
+ return node;
+}
+
+static void
+add (GtkRbTree *tree,
+ guint pos)
+{
+ Node *node = get (tree, pos);
+
+ gtk_rb_tree_insert_before (tree, node);
+}
+
+static void
+delete (GtkRbTree *tree,
+ guint pos)
+{
+ Node *node = get (tree, pos);
+
+ gtk_rb_tree_remove (tree, node);
+}
+
+static guint
+print_node (GtkRbTree *tree,
+ Node *node,
+ guint depth,
+ const char *prefix,
+ guint n)
+{
+ Node *child;
+
+ child = gtk_rb_tree_get_left (tree, node);
+ if (child)
+ n = print_node (tree, child, depth + 1, "/", n);
+ g_print ("%*s %u\n", 2 * depth, prefix, n);
+ n++;
+ child = gtk_rb_tree_get_right (tree, node);
+ if (child)
+ n = print_node (tree, child, depth + 1, "\\", n);
+
+ return n;
+}
+
+static void
+print (GtkRbTree *tree)
+{
+ print_node (tree, gtk_rb_tree_get_root (tree), 0, "", 0);
+}
+
+static void
+test_crash (void)
+{
+ GtkRbTree *tree;
+ guint i;
+
+ tree = gtk_rb_tree_new (Node, Aug, augment, NULL, NULL);
+
+ for (i = 0; i < 300; i++)
+ add (tree, i);
+ print (tree);
+ delete (tree, 144);
+ add (tree, 56);
+ delete (tree, 113);
+ delete (tree, 278);
+ delete (tree, 45);
+ delete (tree, 108);
+ delete (tree, 41);
+ add (tree, 56);
+ add (tree, 200);
+ delete (tree, 127);
+ delete (tree, 222);
+ add (tree, 80);
+ add (tree, 143);
+ add (tree, 216);
+ delete (tree, 177);
+ delete (tree, 193);
+ add (tree, 190);
+ delete (tree, 288);
+ add (tree, 45);
+ add (tree, 57);
+ add (tree, 211);
+ delete (tree, 103);
+ add (tree, 152);
+ delete (tree, 60);
+ add (tree, 185);
+ delete (tree, 167);
+ add (tree, 92);
+ delete (tree, 104);
+ delete (tree, 110);
+ delete (tree, 115);
+ add (tree, 32);
+ delete (tree, 44);
+ add (tree, 159);
+ add (tree, 271);
+ delete (tree, 35);
+ add (tree, 250);
+ delete (tree, 36);
+ add (tree, 284);
+ delete (tree, 82);
+ delete (tree, 248);
+ add (tree, 22);
+ delete (tree, 284);
+ add (tree, 88);
+ delete (tree, 182);
+ add (tree, 70);
+ add (tree, 55);
+ delete (tree, 6);
+ add (tree, 85);
+ delete (tree, 36);
+ delete (tree, 33);
+ delete (tree, 108);
+ add (tree, 229);
+ delete (tree, 269);
+ add (tree, 20);
+ add (tree, 170);
+ delete (tree, 154);
+ add (tree, 26);
+ add (tree, 211);
+ delete (tree, 167);
+ add (tree, 183);
+ add (tree, 292);
+ delete (tree, 2);
+ add (tree, 5);
+ delete (tree, 14);
+ delete (tree, 91);
+ add (tree, 172);
+ add (tree, 99);
+ delete (tree, 3);
+ delete (tree, 74);
+ delete (tree, 122);
+ add (tree, 87);
+ add (tree, 176);
+ delete (tree, 294);
+ add (tree, 169);
+ delete (tree, 41);
+ add (tree, 95);
+ delete (tree, 185);
+ add (tree, 218);
+ delete (tree, 62);
+ delete (tree, 175);
+ add (tree, 196);
+ delete (tree, 33);
+ delete (tree, 46);
+ add (tree, 30);
+ add (tree, 72);
+ delete (tree, 196);
+ delete (tree, 291);
+ add (tree, 198);
+ delete (tree, 181);
+ add (tree, 105);
+ delete (tree, 75);
+ add (tree, 30);
+ add (tree, 261);
+ delete (tree, 284);
+ delete (tree, 214);
+ delete (tree, 134);
+ add (tree, 153);
+ delete (tree, 46);
+ add (tree, 154);
+ add (tree, 266);
+ delete (tree, 272);
+ delete (tree, 150);
+ add (tree, 131);
+ delete (tree, 208);
+ add (tree, 241);
+ add (tree, 31);
+ add (tree, 151);
+ add (tree, 266);
+ delete (tree, 285);
+ add (tree, 178);
+ add (tree, 159);
+ add (tree, 203);
+ delete (tree, 266);
+ add (tree, 52);
+ delete (tree, 104);
+ add (tree, 243);
+ delete (tree, 12);
+ add (tree, 20);
+ delete (tree, 68);
+ print (tree);
+ delete (tree, 102);
+
+ gtk_rb_tree_unref (tree);
+}
+
+int
+main (int argc, char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+ setlocale (LC_ALL, "C");
+ g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
+
+ g_test_add_func ("/csrbtree/crash", test_crash);
+
+ return g_test_run ();
+}